package com.gym.core.common;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * just copy tools
 * 
 * @author xinchun.wang
 * @email: 532002108@qq.com
 * @createTime 2015-1-6 下午3:30:37
 */
public class ZipUtils {

	private final static Logger logger = LoggerFactory
			.getLogger(BeanUtil.class);

	/**
	 * Answer a byte array compressed in the Zip format from bytes.
	 * 
	 * @param bytes
	 *            a byte array
	 * @param aName
	 *            a String the represents a file name
	 * @return byte[] compressed bytes
	 * @throws IOException
	 */
	public static byte[] zipBytes(byte[] bytes, String fileName)
			throws IOException {
		ByteArrayOutputStream tempOStream = null;
		BufferedOutputStream tempBOStream = null;
		ZipOutputStream tempZStream = null;
		ZipEntry tempEntry = null;
		byte[] tempBytes = null;

		tempOStream = new ByteArrayOutputStream(bytes.length);
		tempBOStream = new BufferedOutputStream(tempOStream);
		tempZStream = new ZipOutputStream(tempBOStream);
		tempEntry = new ZipEntry(fileName);
		tempEntry.setMethod(ZipEntry.DEFLATED);
		tempEntry.setSize((long) bytes.length);

		tempZStream.putNextEntry(tempEntry);
		tempZStream.write(bytes, 0, bytes.length);
		tempZStream.flush();
		tempBOStream.flush();
		tempOStream.flush();
		tempZStream.closeEntry();
		tempZStream.close();
		tempBytes = tempOStream.toByteArray();
		tempOStream.close();
		tempBOStream.close();
		return tempBytes;
	}

	/**
	 * Answer a byte array that has been decompressed from the Zip format.
	 * 
	 * @param bytes
	 *            a byte array of compressed bytes
	 * @return byte[] uncompressed bytes
	 * @throws IOException
	 */
	public static void unzipBytes(byte[] bytes, OutputStream os)
			throws IOException {
		ByteArrayInputStream tempIStream = null;
		BufferedInputStream tempBIStream = null;
		ZipInputStream tempZIStream = null;
		ZipEntry tempEntry = null;
		long tempDecompressedSize = -1;
		byte[] tempUncompressedBuf = null;

		tempIStream = new ByteArrayInputStream(bytes, 0, bytes.length);
		tempBIStream = new BufferedInputStream(tempIStream);
		tempZIStream = new ZipInputStream(tempBIStream);
		tempEntry = tempZIStream.getNextEntry();

		if (tempEntry != null) {
			tempDecompressedSize = tempEntry.getCompressedSize();
			if (tempDecompressedSize < 0) {
				tempDecompressedSize = Long.parseLong(tempEntry.getName());
			}

			int size = (int) tempDecompressedSize;
			tempUncompressedBuf = new byte[size];
			int num = 0, count = 0;
			while (true) {
				count = tempZIStream.read(tempUncompressedBuf, 0, size - num);
				num += count;
				os.write(tempUncompressedBuf, 0, count);
				os.flush();
				if (num >= size)
					break;
			}
		}
		tempZIStream.closeEntry();
		tempZIStream.close();
	}

	/***
	 * 压缩GZip
	 * 
	 * @param data
	 * @return
	 */
	public static byte[] gZip(byte[] data) {
		byte[] b = null;
		try {
			ByteArrayOutputStream bos = new ByteArrayOutputStream();
			GZIPOutputStream gzip = new GZIPOutputStream(bos);
			gzip.write(data);
			gzip.finish();
			gzip.close();
			b = bos.toByteArray();
			bos.close();
		} catch (Exception e) {
			logger.error("error", e);
		}
		return b;
	}

	/***
	 * 解压GZip
	 * 
	 * @param data
	 * @return
	 */
	public static byte[] unGZip(byte[] data) {
		if (null == data || 0 == data.length) {
			return new byte[0];
		}

		byte[] b = null;
		try {
			ByteArrayInputStream bis = new ByteArrayInputStream(data);
			GZIPInputStream gzip = new GZIPInputStream(bis);
			byte[] buf = new byte[1024];
			int num = -1;
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			while ((num = gzip.read(buf, 0, buf.length)) != -1) {
				baos.write(buf, 0, num);
			}
			b = baos.toByteArray();
			baos.flush();
			baos.close();
			gzip.close();
			bis.close();
		} catch (Exception e) {
			logger.error("error", e);
		}
		return b;
	}

	/***
	 * 压缩Zip
	 * 
	 * @param data
	 * @return
	 */
	public static byte[] zip(byte[] data) {
		byte[] b = null;
		try {
			ByteArrayOutputStream bos = new ByteArrayOutputStream();
			ZipOutputStream zip = new ZipOutputStream(bos);
			ZipEntry entry = new ZipEntry("zip");
			entry.setSize(data.length);
			zip.putNextEntry(entry);
			zip.write(data);
			zip.closeEntry();
			zip.close();
			b = bos.toByteArray();
			bos.close();
		} catch (Exception e) {
			logger.error("error", e);
		}
		return b;
	}

	public static void main(String[] args) throws IOException {
		byte[] bytes = "sdafjkasfhjkaf".getBytes();
		byte[] out = zipBytes(bytes, "data.xls");
		FileOutputStream of = new FileOutputStream("D:/aaa.zip");
		of.write(out);
		of.flush();
		of.close();

	}

}
